package com.huifer.wgx.utlis;

import static com.huifer.wgx.utlis.ListUtil.strList2ListMap;

import com.huifer.wgx.annotation.CsvFieldAnn;
import com.huifer.wgx.pojo.CsvFieldLine;
import com.huifer.wgx.pojo.CsvFieldPoint;
import com.huifer.wgx.pojo.CsvRtk;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;

import javax.smartcardio.CardTerminal;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

/**
 * <p>Title : CsvUtil </p>
 * <p>Description : csv 工具</p>
 *
 * @author huifer
 * @date 2019-03-20
 */
public class CsvUtil {

    private static final char DEFAULT_SEPARATOR = ',';
    private static final char DEFAULT_QUOTE = '"';

    public static void main(String[] args) throws Exception {
        String csvFile = "E:\\work-java\\wgx\\swagger\\testData\\rtk测试数据csv.csv";
        Iterator<CsvRtk> csvRtkIterator = csvRtkReader(csvFile);
        while (csvRtkIterator.hasNext()) {
            System.out.println(csvRtkIterator.next());
        }
        System.out.println("===================================");
        String csvFile2 = "E:\\work-java\\wgx\\swagger\\testData\\外业采集点测试数据csv.csv";
        Iterator<CsvFieldPoint> csvFieldPointIterator = csvFieldPointReader(csvFile2);
        while (csvFieldPointIterator.hasNext()) {
            System.out.println(csvFieldPointIterator.next());
        }
        System.out.println("===================================");
        String csvFile3 = "E:\\work-java\\wgx\\swagger\\testData\\外业采集线段测试数据csv.csv";
        Iterator<CsvFieldLine> csvFieldLineIterator = csvFieldLineRender(csvFile3);
        while (csvFieldLineIterator.hasNext()) {
            System.out.println(csvFieldLineIterator.next());
        }


    }

    private static List<List<String>> csvRead(String csvFile) throws FileNotFoundException {
        List<List<String>> ls = new ArrayList<>();
        Scanner scanner = new Scanner(new File(csvFile));
        while (scanner.hasNext()) {
            List<String> line = parseLine(scanner.nextLine());
            ls.add(line);
        }
        return ls;
    }


    /**
     * 读取rtk 文件
     *
     * @param getcPath rtk文件位置
     * @return csvrtk 迭代器
     * @throws Exception 异常
     */
    public static Iterator<CsvRtk> csvRtkReader(String getcPath) throws Exception {

        List<List<String>> lists = csvRead(getcPath);
        List<HashMap<String, String>> hashMaps = strList2ListMap(lists);
        Field[] allFields = FieldUtils.getAllFields(CsvRtk.class);
        List<CsvRtk> csvRtkList = new ArrayList<>();
        for (int i = 0; i < hashMaps.size(); i++) {
            HashMap<String, String> stringStringHashMap = hashMaps.get(i);
            CsvRtk crtk = new CsvRtk();

            for (Field allField : allFields) {
                //         CsvFieldAnn注解解析
                CsvFieldAnn annotation = allField.getAnnotation(CsvFieldAnn.class);
                String s = annotation.fieldName();
                String s1 = stringStringHashMap.get(s);
                if (s.equals("id")) {
                    crtk.setId(Long.valueOf(i));
                } else if (s.equals("x")) {
                    crtk.setX(new BigDecimal(s1));
                } else if (s.equals("y")) {
                    crtk.setY(new BigDecimal(s1));
                } else if (s.equals("z")) {
                    crtk.setZ(new BigDecimal(s1));
                } else if (s.equals("name")) {
                    crtk.setName(s1);
                }
            }
            csvRtkList.add(crtk);

        }


        return csvRtkList.iterator();
    }

    /**
     * readCsvLine
     *
     * @param cvsLine csvLine
     * @return 这一行数据
     */
    private static List<String> parseLine(String cvsLine) {
        return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
    }

    /**
     * readCsvLine
     *
     * @param cvsLine    csvLine
     * @param separators 分割符
     * @return 这一行数据
     */
    private static List<String> parseLine(String cvsLine, char separators) {
        return parseLine(cvsLine, separators, DEFAULT_QUOTE);
    }

    /**
     * readCsvLine
     *
     * @param cvsLine     csvLine
     * @param separators  分割符
     * @param customQuote 字符串引号
     * @return 这一行数据
     */
    private static List<String> parseLine(String cvsLine, char separators, char customQuote) {

        List<String> result = new ArrayList<>();

        if (cvsLine == null && cvsLine.isEmpty()) {
            return result;
        }
        if (customQuote == ' ') {
            customQuote = DEFAULT_QUOTE;
        }
        if (separators == ' ') {
            separators = DEFAULT_SEPARATOR;
        }
        StringBuffer curVal = new StringBuffer();
        boolean inQuotes = false;
        boolean startCollectChar = false;
        boolean doubleQuotesInColumn = false;
        char[] chars = cvsLine.toCharArray();
        for (char ch : chars) {
            if (inQuotes) {
                startCollectChar = true;
                if (ch == customQuote) {
                    inQuotes = false;
                    doubleQuotesInColumn = false;
                } else {
                    if (ch == '\"') {
                        if (!doubleQuotesInColumn) {
                            curVal.append(ch);
                            doubleQuotesInColumn = true;
                        }
                    } else {
                        curVal.append(ch);
                    }
                }
            } else {
                if (ch == customQuote) {
                    inQuotes = true;
                    if (chars[0] != '"' && customQuote == '\"') {
                        curVal.append('"');
                    }
                    if (startCollectChar) {
                        curVal.append('"');
                    }
                } else if (ch == separators) {
                    result.add(curVal.toString());
                    curVal = new StringBuffer();
                    startCollectChar = false;
                } else if (ch == '\r') {
                    continue;
                } else if (ch == '\n') {
                    break;
                } else {
                    curVal.append(ch);
                }
            }
        }
        result.add(curVal.toString());
        return result;
    }

    /**
     * 读取外业采集点内容
     *
     * @param getcPath 外业采集点信息
     * @return 外业采集点迭代器
     * @throws Exception 异常
     */
    public static Iterator<CsvFieldPoint> csvFieldPointReader(String getcPath) throws Exception {

        List<List<String>> lists = csvRead(getcPath);
        List<HashMap<String, String>> hashMaps = strList2ListMap(lists);
        Field[] allFields = FieldUtils.getAllFields(CsvFieldPoint.class);
        List<CsvFieldPoint> csvFieldPoints = new ArrayList<>();
        for (int i = 0; i < hashMaps.size(); i++) {
            HashMap<String, String> stringStringHashMap = hashMaps.get(i);
            CsvFieldPoint csvFieldPoint = new CsvFieldPoint();

            for (Field allField : allFields) {
                CsvFieldAnn annotation = allField.getAnnotation(CsvFieldAnn.class);
                String s = annotation.fieldName();
                String s1 = stringStringHashMap.get(s);
                if (s.equals("id")) {
                    csvFieldPoint.setId(Long.valueOf(i));
                } else if (s.equals("名称")) {
                    csvFieldPoint.setName(s1);
                } else if (s.equals("井盖类型")) {
                    csvFieldPoint.setCoverType(s1);
                } else if (s.equals("有无网罩")) {
                    csvFieldPoint.setIsMesh(s1);
                } else if (s.equals("井盖尺寸")) {
                    csvFieldPoint.setSize(s1);
                } else if (s.equals("埋深(米)")) {
                    csvFieldPoint.setDeep(new BigDecimal(s1));
                }
            }
            csvFieldPoints.add(csvFieldPoint);

        }

        return csvFieldPoints.iterator();
    }


    public static Iterator<CsvFieldLine> csvFieldLineRender(String getcPath) throws Exception {
        List<List<String>> lists = csvRead(getcPath);
        List<HashMap<String, String>> hashMaps = strList2ListMap(lists);
        Field[] allFields = FieldUtils.getAllFields(CsvFieldLine.class);
        List<CsvFieldLine> csvFieldLines = new ArrayList<>();
        for (int i = 0; i < hashMaps.size(); i++) {
            HashMap<String, String> stringStringHashMap = hashMaps.get(i);
            CsvFieldLine line = new CsvFieldLine();

            for (Field allField : allFields) {
                CsvFieldAnn annotation = allField.getAnnotation(CsvFieldAnn.class);
                String s = annotation.fieldName();
                String s1 = stringStringHashMap.get(s);
                if (s.equals("id")) {
                    line.setId(Long.valueOf(i));
                } else if (s.equals("起点点名")) {
                    line.setStartName(s1);
                } else if (s.equals("起点埋深(米)")) {
                    line.setStartDeep(new BigDecimal(s1));
                } else if (s.equals("终点点名")) {
                    line.setEndName(s1);
                } else if (s.equals("终点埋深(米)")) {
                    line.setEndDeep(new BigDecimal(s1));
                } else if (s.equals("管径(毫米)")) {
                    line.setDs(s1);
                } else if (s.equals("管材")) {
                    line.setMaterial(s1);
                }
            }
            csvFieldLines.add(line);

        }

        return csvFieldLines.iterator();
    }
}
